package cn.easyutil.veteran.core.condition;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.util.*;

/**
 * 将对象类型的规则引擎转换成表达式
 */
public class ConditionParser {

    /**
     * 将规则对象解析为表达式
     * @param entity 规则对象
     * @return  表达式
     */
    public static String parseToExpression(ConditionEntity entity){
        if(entity == null){
            return "";
        }
        if(StringUtils.isBlank(entity.getExpression()) && CollectionUtils.isEmpty(entity.getChildren())){
            return "";
        }
        if(CollectionUtils.isEmpty(entity.getChildren())){
            return "("+entity.getExpression()+")";
        }
        List<ConditionEntity> children = entity.getChildren();
        StringBuilder result = new StringBuilder();
        result.append("(");
        deepGroup(children,result,entity.getJoinOperator().operate);
        result.append(")");
        return result.toString();
    }

    private static void deepGroup(List<ConditionEntity> children, StringBuilder group, String operate){
        ConditionJoinOperatorEnum lastJoinType = null;
        for (ConditionEntity item : children) {
            if(StringUtils.isBlank(item.getExpression()) && CollectionUtils.isEmpty(item.getChildren())){
                return ;
            }
            if(CollectionUtils.isEmpty(item.getChildren())){
                group.append(item.getExpression());
            }else{
                StringBuilder childrenGroup = new StringBuilder();
                childrenGroup.append("(");
                deepGroup(item.getChildren(),childrenGroup, item.getJoinOperator().operate);
                childrenGroup.append(")");
                group.append(childrenGroup);
            }
            lastJoinType = item.getJoinOperator();
            group.append(operate);
        }

        if(lastJoinType != null){
            group.delete(group.lastIndexOf(operate),group.length());
        }
    }

    /**
     * 获取规则引擎使用到的所有属性或事件key
     */
    public static Set<String> getPropertyKeys(ConditionEntity entity){
        Set<String> keys = new HashSet<>();
        deepGetPropertyKeys(entity,keys);
        return keys;
    }

    private static void deepGetPropertyKeys(ConditionEntity entity,Set<String> keys){
        if(entity == null){
            return ;
        }
        if(CollectionUtils.isNotEmpty(entity.getKeys())){
            keys.addAll(entity.getKeys());
        }
        List<ConditionEntity> children = entity.getChildren();
        if(CollectionUtils.isNotEmpty(children)){
            children.forEach(c -> deepGetPropertyKeys(c,keys));
        }
    }
}
